﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2022 kingerrobot
// 版权所有。 
//
// 文件名：CuringCallMaterialImpl
// 文件功能描述：请料订单生成
//
// 创建者：名字 (zzl)
// 时间：2022/1/19 9:36:52
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion

using KingerRobot.MexicoSailunMDC.Dao;

namespace KingerRobot.MexicoSailunMDC.SpiService;

public class CuringCallMaterialImpl : ICuringCallMaterialService
{

    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IBakWmsOutOrderSummary _BakWmsOutOrderSummary = new BBakWmsOutOrderSummary();
    private readonly static IWmsOutOrderMaster _WmsOutOrderMaster = new BWmsOutOrderMaster();
    private readonly static IRcsEquipCuring _RcsEquipCuring = new BRcsEquipCuring();
    private readonly static IWcsEquipLoc _WcsEquipLoc = new BWcsEquipLoc();
    private readonly static IRcsEquip _RcsEquip = new BRcsEquip();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IProdMaterial _ProdMaterial = new BProdMaterial();
    private readonly static ITask _Task = new BTask();
    private readonly static IRcsEquipScanner _RcsEquipScanner = new BRcsEquipScanner();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IWms2MesService _Wms2MesService = new Wms2MesImpl();
    private readonly static IWcsWarehouseCrnMaterial _WcsWarehouseCrnMaterial = new BWcsWarehouseCrnMaterial();

    public (List<CuringCallMaterialResult>, string, int) CreateCallMaterialOrder(List<CuringCallMaterialParam> param,
        int codeOutOrderType = (int)EnumCodeOutOrderType.RequesMaterial)
    {
        var result = new List<CuringCallMaterialResult>();
        string msg = "请料成功";
        try
        {

            // 无请料
            if (param.Count == 0)
            {
                msg = "请料明细未找到";
                return (result, msg, -4);
            }

            // 获取物料对应货位和序号
            //var (outOrderSummaries, remsg, otherIsEmpty) = GetCuringCallMaterialListV2(param, codeOutOrderType);
            var (outOrderSummaries, remsg) = GetCuringCallMaterialList(param, codeOutOrderType);
            if (outOrderSummaries.Count == 0)
            {
                msg = string.IsNullOrWhiteSpace(remsg) ? $"请料出库订单数量{param.Count}实际为{outOrderSummaries.Count},原因:硫化机不存在 / 已经请料" : remsg;
                WriteLog(msg, true);
                return (result, msg, -5);
            }

            if (param.Count != outOrderSummaries.Count)
            {
                //if (!otherIsEmpty)
                //{
                msg = string.IsNullOrWhiteSpace(remsg) ? $"请料出库订单数量{param.Count}与实际请料数量{outOrderSummaries.Count}不一致" : remsg;
                WriteLog(msg, true);
                return (result, msg, -6);
                //}
            }

            //直运标志 默认为非直运(0)
            var directDelivery = 0;
            long? directDeliveryLoc = null;

            // 物料是否相同一个请料订单；物料不同拆分成两个请料单
            var masterIds = new List<long>();
            var specCount = outOrderSummaries.Select(t => t.Spec).Distinct().Count();
            int.TryParse(param.FirstOrDefault()?.OrderPriority.ToString(), out var orderPriority);
            var orderNo = param.FirstOrDefault()?.OrderNo;

            if (specCount == 1)
            {

                // 判断库存是否满足请求数量-非按条码出库类型的订单
                (directDelivery, directDeliveryLoc) = GetDirectDelivery(codeOutOrderType,
                    (int)EnumCodeOutOrderType.WarehouseProductCode,
                    outOrderSummaries);


                // 硫化请料 请料方式通过参数传入 已解决
                var masterId = _WmsOutOrderMaster.AddOutOrderMaster(codeOutOrderType,
                    directDeliveryLoc,
                    directDelivery,
                    orderPriority,
                    orderNo);
                if (masterId == 0)
                {
                    msg = $"请料出库订单主数据创建失败";
                    WriteLog(msg, true);
                    return (result, msg, -7);
                }

                outOrderSummaries.ForEach(item =>
                {
                    item.MasterId = masterId;
                });
                masterIds.Add(masterId);
            }
            else
            {
                //// 若存在库存不足的,则先指定直运扫描仪
                //var isDelivery = outOrderSummaries.Any(t => t.Stock - t.PlanCount < 0);
                //if (isDelivery)
                //{
                //	// 指定直运扫描仪
                //	var scannerId = _RcsEquipScanner.GetDirectDeliveryEquipId();
                //	if (scannerId != 0)
                //	{
                //		directDeliveryLoc = _WcsEquipLoc.GetLocIdByEquipId(scannerId);
                //		_RcsEquipScanner.UpdateDirectDeliveryTime(scannerId);
                //	}
                //}


                var addMasterRes = 0;
                foreach (var item in outOrderSummaries)
                {
                    //if (directDelivery != 1)
                    //{
                    //    (directDelivery, directDeliveryLoc) = GetDirectDelivery(codeOutOrderType,
                    //        (int)EnumCodeOutOrderType.WarehouseProductCode, outOrderSummaries);
                    //}
                    (directDelivery, directDeliveryLoc) = GetDirectDelivery(codeOutOrderType,
                        (int)EnumCodeOutOrderType.WarehouseProductCode, new() { item });

                    var masterId = _WmsOutOrderMaster.AddOutOrderMaster(codeOutOrderType,
                        directDeliveryLoc,
                        directDelivery,
                        orderPriority,
                    orderNo);
                    if (masterId == 0)
                    {
                        msg = $"请料出库订单主数据创建失败";
                        WriteLog(msg, true);
                        addMasterRes++;
                        masterIds.Add(masterId);
                        break;
                    }
                    item.MasterId = masterId;
                }
                if (addMasterRes > 0)
                {
                    // 主表创建失败
                    return (result, msg, -8);
                }
            }
            // 创建从表数据
            var num = _WmsOutOrderSummary.AddOutOrderSummaryList(outOrderSummaries);
            if (num == 0)
            {
                masterIds.ForEach(masterId =>
                {
                    _WmsOutOrderMaster.DeleteOutOderMaster(masterId);
                });
                msg = "请料明细添加失败";
                return (result, msg, 2);
            }

            // 删除硫化机绑定
            outOrderSummaries.ForEach(item =>
            {
                var equip = _WcsEquipLoc.GetEquipIdByLocId(item.TargetLoc);

                var curing = _RcsEquipCuring.GetCuringById(equip);
                if (curing?.IsCuringCall == 0)
                {
                    _WcsLocSku.DeleteWcsLocSkuByLoc(item.TargetLoc);
                }
            });

            result = outOrderSummaries.Select(t => new CuringCallMaterialResult
            {
                Id = t.MidId,
                EquipNo = t.EquipNo,
                EquipModel = t.EquipModel,
                SummaryId = t.SummaryId
            }).ToList();

            //同步MES
            SyncMes(outOrderSummaries);
        }
        catch (Exception ex)
        {
            WriteLog($"请料异常A：{ex.Message}", true);
        }
        return (result, msg, 1);
    }

    private (int, long) GetDirectDelivery(int codeOutOrderType, int outType, List<OutOrderSummary> outOrderSummaries)
    {
        var directDelivery = 0;
        var directDeliveryLoc = 0L;
        // 判断库存是否满足请求数量-非按条码出库类型的订单
        if (codeOutOrderType != outType)
        {
            var isDelivery = outOrderSummaries.Where(t => t.Stock - t.PlanCount < 0).Any();

            // 判断库存设置直运，若库存小于请求数量，则设置为直运
            if (isDelivery)
            {
                // 指定直运扫描仪
                var scannerId = _RcsEquipScanner.GetDirectDeliveryEquipId();
                if (scannerId != 0)
                {
                    directDelivery = 1;
                    directDeliveryLoc = _WcsEquipLoc.GetLocIdByEquipId(scannerId);
                    _RcsEquipScanner.UpdateDirectDeliveryTime(scannerId);
                }
            }
        }

        return (directDelivery, directDeliveryLoc);
    }

    /// <summary>
    /// 同步MES
    /// </summary>
    /// <param name="outOrderSummaries"></param>
    private void SyncMes(List<OutOrderSummary> outOrderSummaries)
    {
        //推送出库订单状态(WMS->MES)
        List<PushOutOrderStatusParam> pushOutOrderStatusParams = new List<PushOutOrderStatusParam>();
        var createdOutOrderSummaries = outOrderSummaries.Where(t => t.SummaryId > 0).ToList();
        foreach (var outOrderSummary in createdOutOrderSummaries)
        {
            // 只有按照条码和库位出库才有
            var tireBarcode = _ProdProduct.GetCodeByLocId(outOrderSummary.StartLoc);
            pushOutOrderStatusParams.Add(new PushOutOrderStatusParam
            {
                OrderDetailId = outOrderSummary.SummaryId.ToString(),
                OrderStatus = (int)EnumPushOutOrderStatus.CreateOrder,
                TireBarcode = tireBarcode
            });
        }
        _Wms2MesService.PushOutOrderStatus(pushOutOrderStatusParams);

        // 按条码出库 / 按规格、数量出库 修改中间表 order_detail_id 字段
        foreach (var outOrderSummary in createdOutOrderSummaries)
        {
            //_Rpc.SetRequestMaterialByEquipNoInfos(outOrderSummary.EquipNo, outOrderSummary.EquipModel, outOrderSummary.SummaryId);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="curingCallMaterials"></param>
    /// <param name="CodeOutOrderType">出库订单类型</param>
    /// <returns></returns>
    private (List<OutOrderSummary>, string) GetCuringCallMaterialList(List<CuringCallMaterialParam> curingCallMaterials, int CodeOutOrderType)
    {
        List<OutOrderSummary> outOrderSummaries = new();
        var currentTime = DateTime.Now;
        string msg = string.Empty;
        try
        {
            // 查找硫化机左右模
            var machineNo = curingCallMaterials.FirstOrDefault().MachineNo;
            var curings = _RcsEquipCuring.GetEquipCuringsByCode(machineNo);
            // 正常请料     【0:正常；1:暂停(已有请料正常执行)；2:停止(已有请料输送至异常口)】
            curings = curings.Where(t => t.CuringStatus == 0).OrderBy(t => t.CuringModeIndex).ToList();
            if (!curings.Any())
            {
                msg = $"硫化机[{machineNo}]非正常状态(暂停或停止)";
                WriteLog(msg, true);
                return (outOrderSummaries, msg);
            }

            if (curingCallMaterials.Count > 2)
            {
                msg = $"硫化机[{machineNo}]无法同时生成{curingCallMaterials.Count}条请料单,最多生成左右模2条";
                WriteLog(msg, true);
                return (outOrderSummaries, msg);
            }

            if (curingCallMaterials.Count > 1)
            {
                var firstCall = curingCallMaterials.First();
                var lastCall = curingCallMaterials.Last();

                if (firstCall.MachineNo.Equals(lastCall.MachineNo) && firstCall.MachineModel == lastCall.MachineModel)
                {
                    msg = $"硫化机[{machineNo}]无法同时生成两条相同硫化模{firstCall.MachineModel}请料";
                    WriteLog(msg, true);
                    return (outOrderSummaries, msg);
                }

            }

            // 物料数量
            int materialCount = curingCallMaterials.Select(t => t.Spec).Distinct().Count();
            int materialIndex = 0;
            int stockNum = 1;
            int planTotalCount = 0;

            foreach (var curing in curings)
            {

                var curingId = curing.Id.GetValueOrDefault();

                // 获取设备是：左模、右模
                var curingRL = _RcsEquipCuring.GetCuringRLByCuringId(curingId);
                var callMaterial = curingCallMaterials.Where(t => t.ModeRL == curingRL?.Mode && !string.IsNullOrWhiteSpace(t.Spec)).FirstOrDefault();
                if (callMaterial is null)
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"{curingRL?.Mode}模请料 请料为空 | {currentTime}");
                    WriteLog($"{curing.CuringCode}-{curingRL?.Mode}模请料 请料为空", true);
                    continue;
                }

                // Ems 小车禁用不可以创建请料单
                var equips = _RcsEquip.GetWorkEquipByIds(new() { curing.EmsId, curing.EmsId2 });
                if (!equips.Any())
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"Ems 小车都被禁用 | {currentTime}");
                    WriteLog($"Ems 小车都被禁用", true);
                    msg = $"{curing.CuringCode} 硫化排Ems小车都被禁用 | ";
                    break;
                }

                // 硫化机具体位置
                var locId = _WcsEquipLoc.GetLocIdByEquipId(curingId);
                if (CodeOutOrderType == (int)EnumCodeOutOrderType.RequesMaterial)
                {
                    // 判断 上次完成时间
                    var finishTime = _BakWmsOutOrderSummary.GetBakWmsOutOrderSummaryByLocId(locId)?.FinishTime;
                    if (finishTime is not null)
                    {
                        // 时间判断
                        if (callMaterial.CanQty <= 0)
                        {
                            //即将满了
                            if (finishTime > DateTime.Now.AddSeconds(-45))
                            {
                                //没到时间
                                _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"请料一条，需要等待上条完成 45 秒后请料 | {currentTime}");
                                WriteLog($"请料一条，需要等待上条完成 45 秒后请料 ", true);
                                msg = $"{curing.CuringCode} 请料一条，需要等待上条完成 45 秒后请料  | ";
                                continue;
                            }
                        }
                    }
                }

                //// 历史版本 V1
                //// 通过货位判断是否已请料(硫化左右模当前只能请料一次)
                //var isCall = _WmsOutOrderSummary.IsOutOrderSummaryByLocId(locId);
                //if (isCall)
                //{
                //    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"已经存在请料单,无法重复创建 | {currentTime}");
                //    msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单,无法重复创建 | ";
                //    continue;
                //}
                //A0411019 - 1已经存在请料单509967834248380476,主表509967833258524732,无法重复创建 | 11 / 08 / 2023 15:44:24
                //A0411019 - 2已经存在请料单509994388093403196,主表509994387430703164,无法重复创建 | 11 / 08 / 2023 15:42:22

                // 新版本V2
                // 通过货位判断是否已请料(硫化左右模当前只能请料一次)
                var locCall = _WmsOutOrderSummary.GetOutOrderSummaryByTargetLocId(locId);
                var isCall = locCall is not null;
                //请料单不为空
                if (isCall)
                {
                    // 判断请料是否一致
                    var materialSpec = _ProdMaterial.GetMaterialBySpec(callMaterial.Spec);
                    if (locCall.MaterialId == materialSpec.Id)
                    {
                        _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单{locCall.Id},主表{locCall.MasterId},无法重复创建 | {currentTime}");
                        msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单,无法重复创建 | ";
                        continue;
                    }
                    else
                    {
                        // 删除旧请料（如果已经生成出库任务，在EMS取胎位找不到请料单生成异常任务）
                        _WmsOutOrderSummary.BakUpdateAndDeleteOutOrderSummary(locCall, $"重新请料{callMaterial.Spec},换模强制删除请料单.");
                        var masterId = locCall.MasterId.GetValueOrDefault();
                        var summaryCount = _WmsOutOrderSummary.GetOutOrderSummaryByMasterId(masterId).Count();
                        if (summaryCount == 0)
                        {
                            var master = _WmsOutOrderMaster.GetOutOrderMasterById(masterId);
                            if (master != null)
                            {
                                _WmsOutOrderMaster.BakOutOderMaster(master);
                                _WmsOutOrderMaster.DeleteOutOderMaster(masterId);
                            }
                        }
                        isCall = false;
                    }
                }


                // 获取实时库存-非按条码出库类型的订单获取实时库存
                if (CodeOutOrderType != (int)EnumCodeOutOrderType.WarehouseProductCode)
                {
                    // 下面是获取实时库存代码
                    var material = _ProdMaterial.GetMaterialBySpec(callMaterial.Spec);
                    if (material is null)
                    {
                        _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"物料[{callMaterial.Spec}]不存在 | {currentTime}");
                        WriteLog($"物料[{callMaterial.Spec}]不存在", true);

                        msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}物料[{callMaterial.Spec}]不存在 | ";
                        break;
                    }
                    // 一个物料或多个物料但物料不同情况下，则获取实时库存
                    if (materialIndex == 0 || (materialIndex > 0 && materialCount > 1))
                    {
                        stockNum = _WcsWarehouseCrnMaterial.GetWareHouseStockNoSummaryByMaterialId(material.Id.GetValueOrDefault());
                    }
                    else
                    {
                        stockNum = stockNum - planTotalCount;
                    }
                }

                int.TryParse(callMaterial.InvQty.ToString(), out var PlanCount);
                planTotalCount += PlanCount;
                //_RcsEquipCuring.UpdateCuringCallRemark(curingId, $"物料[{callMaterial.Spec}],开始添加订单 | {currentTime}");
                try
                {
                    outOrderSummaries.Add(new()
                    {
                        EquipNo = callMaterial.MachineNo,
                        EquipModel = callMaterial.MachineModel,

                        MidId = callMaterial.MidId,
                        SummaryIndex = curing.CuringModeIndex.GetValueOrDefault(),
                        Serno = callMaterial.Serno,
                        TargetLoc = locId,
                        TargetId = curingId,
                        Spec = callMaterial.Spec,
                        MaterialCode = callMaterial.Spec,
                        RotateAngle = callMaterial.Angle,
                        Stock = stockNum,
                        PlanCount = 1,// 郭海朋  
                        StartLoc = callMaterial.StartLoc,
                        IsCall = !isCall,
                        Remark = callMaterial.Remark,
                    });
                    //_RcsEquipCuring.UpdateCuringCallRemark(curingId, $"添加成功");
                    materialIndex++;
                }
                catch (Exception ex)
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"异常{ex.ToString().Substring(0, 490)}");
                }
            }

            if (!outOrderSummaries.Any())
            {
                WriteLog($"没有请料单", true);
                return (outOrderSummaries, msg);
            }

            //// 通过货位判断是否已请料(硫化左右模当前只能请料一次)
            //outOrderSummaries.ForEach(item =>
            //{
            //	item.IsCall = !_WmsOutOrderSummary.IsOutOrderSummaryByLocId(item.TargetLoc);
            //});
        }
        catch (Exception ex)
        {
            msg = $"{msg} | {ex.Message}";
            WriteLog($"请料异常B：{ex.Message},{ex.StackTrace}", true);
        }

        //var notCalls = outOrderSummaries.Where(t => t.IsCall == false).ToList();
        //foreach (var call in notCalls)
        //{
        //	_RcsEquipCuring.UpdateCuringCallRemark(call.TargetId, $"已经存在请料单,无法重复创建 | {currentTime}");
        //}

        return (outOrderSummaries.Where(t => t.IsCall == true).ToList(), msg);
    }


    private (List<OutOrderSummary>, string, bool) GetCuringCallMaterialListV2(List<CuringCallMaterialParam> curingCallMaterials, int CodeOutOrderType)
    {
        List<OutOrderSummary> outOrderSummaries = new();
        var currentTime = DateTime.Now;
        string msg = string.Empty;
        var otherIsEmpty = false;
        try
        {
            // 查找硫化机左右模
            var machineNo = curingCallMaterials.FirstOrDefault().MachineNo;
            var curings = _RcsEquipCuring.GetEquipCuringsByCode(machineNo);
            // 正常请料     【0:正常；1:暂停(已有请料正常执行)；2:停止(已有请料输送至异常口)】
            curings = curings.Where(t => t.CuringStatus == 0).OrderBy(t => t.CuringModeIndex).ToList();
            if (!curings.Any())
            {
                msg = $"硫化机[{machineNo}]非正常状态(暂停或停止)";
                WriteLog(msg, true);
                return (outOrderSummaries, msg, otherIsEmpty);
            }

            if (curingCallMaterials.Count > 2)
            {
                msg = $"硫化机[{machineNo}]无法同时生成{curingCallMaterials.Count}条请料单,最多生成左右模2条";
                WriteLog(msg, true);
                return (outOrderSummaries, msg, otherIsEmpty);
            }

            if (curingCallMaterials.Count > 1)
            {
                var firstCall = curingCallMaterials.First();
                var lastCall = curingCallMaterials.Last();

                if (firstCall.MachineNo.Equals(lastCall.MachineNo) && firstCall.MachineModel == lastCall.MachineModel)
                {
                    msg = $"硫化机[{machineNo}]无法同时生成两条相同硫化模{firstCall.MachineModel}请料";
                    WriteLog(msg, true);
                    return (outOrderSummaries, msg, otherIsEmpty);
                }

            }

            // 物料数量
            int materialCount = curingCallMaterials.Select(t => t.Spec).Distinct().Count();
            int materialIndex = 0;
            int stockNum = 1;
            int planTotalCount = 0;


            foreach (var curing in curings)
            {

                var curingId = curing.Id.GetValueOrDefault();

                // 获取设备是：左模、右模
                var curingRL = _RcsEquipCuring.GetCuringRLByCuringId(curingId);
                var callMaterial = curingCallMaterials.Where(t => t.ModeRL == curingRL?.Mode && !string.IsNullOrWhiteSpace(t.Spec)).FirstOrDefault();
                if (callMaterial is null)
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"{curingRL?.Mode}模请料 请料为空 | {currentTime}");
                    WriteLog($"{curing.CuringCode}-{curingRL?.Mode}模请料 请料为空", true);
                    continue;
                }

                // Ems 小车禁用不可以创建请料单
                var equips = _RcsEquip.GetWorkEquipByIds(new() { curing.EmsId, curing.EmsId2 });
                if (!equips.Any())
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"Ems 小车都被禁用 | {currentTime}");
                    WriteLog($"Ems 小车都被禁用", true);
                    msg = $"{curing.CuringCode} 硫化排Ems小车都被禁用 | ";
                    break;
                }

                // 硫化机具体位置
                var locId = _WcsEquipLoc.GetLocIdByEquipId(curingId);
                if (CodeOutOrderType == (int)EnumCodeOutOrderType.RequesMaterial)
                {
                    // 判断 上次完成时间
                    var finishTime = _BakWmsOutOrderSummary.GetBakWmsOutOrderSummaryByLocId(locId)?.FinishTime;
                    if (finishTime is not null)
                    {
                        // 时间判断
                        if (callMaterial.CanQty <= 0)
                        {
                            //即将满了
                            if (finishTime > DateTime.Now.AddSeconds(-45))
                            {
                                //没到时间
                                _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"请料一条，需要等待上条完成 45 秒后请料 | {currentTime}");
                                WriteLog($"请料一条，需要等待上条完成 45 秒后请料 ", true);
                                msg = $"{curing.CuringCode} 请料一条，需要等待上条完成 45 秒后请料  | ";
                                continue;
                            }
                        }
                    }
                }

                //// 历史版本 V1
                //// 通过货位判断是否已请料(硫化左右模当前只能请料一次)
                //var isCall = _WmsOutOrderSummary.IsOutOrderSummaryByLocId(locId);
                //if (isCall)
                //{
                //    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"已经存在请料单,无法重复创建 | {currentTime}");
                //    msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单,无法重复创建 | ";
                //    continue;
                //}

                // 新版本V2
                // 通过货位判断是否已请料(硫化左右模当前只能请料一次)
                var locCall = _WmsOutOrderSummary.GetOutOrderSummaryByTargetLocId(locId);
                var isCall = locCall is not null;
                //请料单不为空
                if (isCall)
                {
                    // 判断请料是否一致
                    var materialSpec = _ProdMaterial.GetMaterialBySpec(callMaterial.Spec);
                    if (locCall.MaterialId == materialSpec.Id)
                    {
                        _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单{locCall.Id},主表{locCall.MasterId},无法重复创建 | {currentTime}");
                        msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}已经存在请料单,无法重复创建 | ";
                        otherIsEmpty = true;
                        continue;
                    }
                    else
                    {
                        // 删除旧请料（如果已经生成出库任务，在EMS取胎位找不到请料单生成异常任务）
                        _WmsOutOrderSummary.BakUpdateAndDeleteOutOrderSummary(locCall, $"重新请料{callMaterial.Spec},换模强制删除请料单.");
                        var masterId = locCall.MasterId.GetValueOrDefault();
                        var summaryCount = _WmsOutOrderSummary.GetOutOrderSummaryByMasterId(masterId).Count();
                        if (summaryCount == 0)
                        {
                            var master = _WmsOutOrderMaster.GetOutOrderMasterById(masterId);
                            if (master != null)
                            {
                                _WmsOutOrderMaster.BakOutOderMaster(master);
                                _WmsOutOrderMaster.DeleteOutOderMaster(masterId);
                            }
                        }
                        isCall = false;
                    }
                }


                // 获取实时库存-非按条码出库类型的订单获取实时库存
                if (CodeOutOrderType != (int)EnumCodeOutOrderType.WarehouseProductCode)
                {
                    // 下面是获取实时库存代码
                    var material = _ProdMaterial.GetMaterialBySpec(callMaterial.Spec);
                    if (material is null)
                    {
                        _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"物料[{callMaterial.Spec}]不存在 | {currentTime}");
                        WriteLog($"物料[{callMaterial.Spec}]不存在", true);

                        msg = $"{curing.CuringCode}-{curingRL?.ModeIndex}物料[{callMaterial.Spec}]不存在 | ";
                        break;
                    }
                    // 一个物料或多个物料但物料不同情况下，则获取实时库存
                    if (materialIndex == 0 || (materialIndex > 0 && materialCount > 1))
                    {
                        stockNum = _WcsWarehouseCrnMaterial.GetWareHouseStockNoSummaryByMaterialId(material.Id.GetValueOrDefault());
                    }
                    else
                    {
                        stockNum = stockNum - planTotalCount;
                    }
                }

                int.TryParse(callMaterial.InvQty.ToString(), out var PlanCount);
                planTotalCount += PlanCount;
                //_RcsEquipCuring.UpdateCuringCallRemark(curingId, $"物料[{callMaterial.Spec}],开始添加订单 | {currentTime}");
                try
                {
                    outOrderSummaries.Add(new()
                    {
                        EquipNo = callMaterial.MachineNo,
                        EquipModel = callMaterial.MachineModel,

                        MidId = callMaterial.MidId,
                        SummaryIndex = curing.CuringModeIndex.GetValueOrDefault(),
                        Serno = callMaterial.Serno,
                        TargetLoc = locId,
                        TargetId = curingId,
                        Spec = callMaterial.Spec,
                        MaterialCode = callMaterial.Spec,
                        RotateAngle = callMaterial.Angle,
                        Stock = stockNum,
                        PlanCount = 1,// 郭海朋  
                        StartLoc = callMaterial.StartLoc,
                        IsCall = !isCall,
                        Remark = callMaterial.Remark,
                    });
                    //_RcsEquipCuring.UpdateCuringCallRemark(curingId, $"添加成功");
                    materialIndex++;
                }
                catch (Exception ex)
                {
                    _RcsEquipCuring.UpdateCuringCallRemark(curingId, $"异常{ex.ToString().Substring(0, 490)}");
                }
            }

            if (!outOrderSummaries.Any())
            {
                WriteLog($"没有请料单", true);
                return (outOrderSummaries, msg, otherIsEmpty);
            }

            //// 通过货位判断是否已请料(硫化左右模当前只能请料一次)
            //outOrderSummaries.ForEach(item =>
            //{
            //	item.IsCall = !_WmsOutOrderSummary.IsOutOrderSummaryByLocId(item.TargetLoc);
            //});
        }
        catch (Exception ex)
        {
            msg = $"{msg} | {ex.Message}";
            WriteLog($"请料异常B：{ex.Message},{ex.StackTrace}", true);
        }

        //var notCalls = outOrderSummaries.Where(t => t.IsCall == false).ToList();
        //foreach (var call in notCalls)
        //{
        //	_RcsEquipCuring.UpdateCuringCallRemark(call.TargetId, $"已经存在请料单,无法重复创建 | {currentTime}");
        //}

        return (outOrderSummaries.Where(t => t.IsCall == true).ToList(), msg, otherIsEmpty);
    }

    /// <summary>
    /// 通过物料Id获取实时库存
    /// </summary>
    /// <param name="materialId"></param>
    /// <returns></returns>
    public int GetStockByMateriaId(long materialId)
    {
        var dbHelper = new DbHelper();
        var sql = new StringBuilder();
        //sql.Append(@$"select 1 from rcs_location t left join 
        //            (SELECT  * FROM (SELECT  b.*, ROW_NUMBER() OVER (partition BY loc_id
        //             ORDER BY create_time DESC) AS px FROM  wcs_loc_sku b) e WHERE   px = 1) AS s
        //             on t.objid=s.loc_id left join prod_sku_product k on s.sku_id=k.sku_id left join prod_product p on p.objid=k.product_id
        //            where t.loc_type=33 and t.loc_has_sku=1 and t.loc_enable=1 and t.out_enable=1
        //            and p.frozen=0 and p.gt_status='0'");

        //sql.Append($"and  t.material_id = '{materialId}'");
        //dbHelper.CommandText = sql.ToString();
        //dbHelper.CommandType = System.Data.CommandType.Text;
        //var data = dbHelper.GetXDataTable();
        //var stockNum = data.Rows.Count();

        sql.Append(@$"with loc as (
				select t.material_id,count(1) as num from rcs_location t 
				left join (SELECT  e.loc_id,e.sku_id FROM (SELECT  b.loc_id,b.sku_id, ROW_NUMBER() OVER (partition BY loc_id
						ORDER BY create_time DESC) AS px FROM  wcs_loc_sku b) e WHERE e.px = 1) AS s on t.objid=s.loc_id 
				left join prod_sku_product k on s.sku_id=k.sku_id 
				left join prod_product p on p.objid=k.product_id
				where t.loc_type=33 and t.loc_has_sku=1 and t.loc_enable=1 and t.out_enable=1
				and p.frozen=0 and p.gt_status='0'
				and  t.material_id = '{materialId}'
				group by t.material_id)
				select loc.material_id,loc.num-ISNULL(summary.num,0)-ISNULL(taskcmd.num,0) as stocknum from loc
				left join (select material_id, sum(plan_count - real_count) as num 
							from wms_out_order_summary where material_id = '{materialId}' 
							group by material_id) as summary  on loc.material_id=summary.material_id
				left join (select sku.material_id,COUNT(1) as num from  wcs_task task 
							inner join wcs_task_cmd cmd on cmd.task_id=task.objid
							inner join prod_sku sku on task.sku_id=sku.objid
							where cmd.cmd_type=2 and cmd.cmd_status<9 and sku.material_id='{materialId}' 
							group by sku.material_id) taskcmd on loc.material_id=taskcmd.material_id");

        dbHelper.CommandText = sql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;
        var data = dbHelper.GetXDataTable();
        int stockNum = 0;
        if (data.Rows.Count() > 0)
        {
            int.TryParse(data.Rows[0]["stocknum"], out stockNum);
        }

        return stockNum;
    }
}